[PM-34828] Fix BW lite sqlite bulk import failure for org imports#7468
[PM-34828] Fix BW lite sqlite bulk import failure for org imports#7468mimartin12 wants to merge 4 commits intomainfrom
Conversation
Bitwarden Claude Code ReviewOverall Assessment: APPROVE This PR extends the SQLite Code Review DetailsNo findings. |
|
New Issues (2)Checkmarx found the following issues in this Pull Request
|
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #7468 +/- ##
==========================================
+ Coverage 58.56% 63.61% +5.05%
==========================================
Files 2063 2077 +14
Lines 91188 91881 +693
Branches 8123 8182 +59
==========================================
+ Hits 53401 58450 +5049
+ Misses 35878 31412 -4466
- Partials 1909 2019 +110 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
justindbaur
left a comment
There was a problem hiding this comment.
I'm cautious about this change, there could be many other places that are broken and it forces us to do more and more branching when the goal is that we don't have to branch for EF unless absolutely needed.
I wonder if we could configure the provider explicitly like this:
diff --git a/src/Infrastructure.EntityFramework/EntityFrameworkServiceCollectionExtensions.cs b/src/Infrastructure.EntityFramework/EntityFrameworkServiceCollectionExtensions.cs
index e2227167a6..af66106e81 100644
--- a/src/Infrastructure.EntityFramework/EntityFrameworkServiceCollectionExtensions.cs
+++ b/src/Infrastructure.EntityFramework/EntityFrameworkServiceCollectionExtensions.cs
@@ -1,4 +1,5 @@
-using Bit.Core.AdminConsole.Repositories;
+using System.Diagnostics;
+using Bit.Core.AdminConsole.Repositories;
using Bit.Core.Auth.Repositories;
using Bit.Core.Billing.Organizations.Repositories;
using Bit.Core.Billing.Providers.Repositories;
@@ -25,6 +26,7 @@ using Bit.Infrastructure.EntityFramework.Repositories;
using Bit.Infrastructure.EntityFramework.SecretsManager.Repositories;
using Bit.Infrastructure.EntityFramework.Tools.Repositories;
using Bit.Infrastructure.EntityFramework.Vault.Repositories;
+using LinqToDB;
using LinqToDB.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
@@ -40,9 +42,6 @@ public static class EntityFrameworkServiceCollectionExtensions
throw new Exception($"Database provider type {provider} was selected but no connection string was found.");
}
- // TODO: We should move away from using LINQ syntax for EF (TDL-48).
- LinqToDBForEFTools.Initialize();
-
services.AddAutoMapper(typeof(UserRepository));
services.AddDbContext<DatabaseContext>(options =>
{
@@ -65,6 +64,35 @@ public static class EntityFrameworkServiceCollectionExtensions
{
options.UseSqlServer(connectionString);
}
+
+ // Configure LinqToDB with the types of drivers we use for each DB type, this allows to us avoid it searching
+ // for assemblies and gives us the ability to publish as a single file.
+ options.UseLinqToDB(linq =>
+ {
+ linq.AddCustomOptions(linqOptions =>
+ {
+ if (provider == SupportedDatabaseProviders.Postgres)
+ {
+ return linqOptions.UsePostgreSQL();
+ }
+ else if (provider == SupportedDatabaseProviders.MySql)
+ {
+ return linqOptions.UseMySqlConnector();
+ }
+ else if (provider == SupportedDatabaseProviders.Sqlite)
+ {
+ return linqOptions.UseSQLiteMicrosoft();
+ }
+ else if (provider == SupportedDatabaseProviders.SqlServer)
+ {
+ return linqOptions.UseSqlServer(provider: LinqToDB.DataProvider.SqlServer.SqlServerProvider.MicrosoftDataSqlClient);
+ }
+
+ Debug.Fail("Unknown database provider.");
+
+ return linqOptions;
+ });
+ });
});
}
Hopefully by manually telling it the provider we avoid having to have it search for it. If this doesn't work and we need to start branching then we especially need to make sure that these differences are now covered by tests.





🎟️ Tracking
https://bitwarden.atlassian.net/browse/PM-34828
📔 Objective
Fixes a 500 error when logging in with an org account and when importing a vault on SQLite environments.
Cause
EventRepository.CreateManyAsyncand two cases ofCipherRepository.CreateAsynccallLinqToDB's BulkCopyAsync. When called against a SQLite context, LinqToDB auto-detects which SQLite
adapter to use by checking for
System.Data.SQLite.dllorMicrosoft.Data.Sqlite.dllon disk. Since theserver publishes as a single-file bundle (PublishSingleFile=true), managed DLLs are embedded in the
executable and not present on disk (example).
This surfaced after a change in the build process for the Bitwarden Lite container, which now pulls directly from our existing built containers.
bitwarden/self-host@08922d4
Changes in this PR
Added IsSqlite() guards to three methods to route SQLite through EF Core's AddRangeAsync/SaveChangesAsync instead of LinqToDB's BulkCopyAsync:
📸 Screenshots